﻿// <copyright file="NewsSections.cs" company="Microsoft Corporation">
// Copyright (c) 2010 Microsoft Corporation All Rights Reserved
// </copyright>
// <author>Michael S. Scherotter</author>
// <email>mischero@microsoft.com</email>
// <date>2010-06-04</date>
// <summary>NewsSections class definition</summary>

namespace NYTimes
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Media.Imaging;
    using System.Xml.Linq;
    using NYTimes.Core;
    using NYTimes.Data;

    /// <summary>
    /// Get News Section Names
    /// http://api.nytimes.com/svc/news/v3/content/section-list.xml?api-key=b92eac2a3c7ad403d32423f9ecff9e07:11:57351476
    /// </summary>
    public class NewsSections : INotifyPropertyChanged
    {
        #region Fields
        /// <summary>
        /// the NYT Newswire Key in the App resources
        /// </summary>
        private const string NYTNewswireKey = "NYTNewswireKey";

        /// <summary>
        /// the API Key
        /// </summary>
        private string apiKey;

        /// <summary>
        /// the result status 
        /// </summary>
        private string status;

        /// <summary>
        /// the copyright message
        /// </summary>
        private string copyright;

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the NewsSections class
        /// </summary>
        public NewsSections()
        {
            this.SectionNames = new ObservableCollection<NewsSection>();

            if (Application.Current.Resources.Contains(NYTNewswireKey))
            {
                this.ApiKey = Application.Current.Resources[NYTNewswireKey] as string;
            }

            if (SampleData.IsInDesignTool)
            {
                var xml = SampleData.GetSampleData("NewsSectionList.xml");

                if (!string.IsNullOrEmpty(xml))
                {
                    this.ParseXml(xml);
                }
            }
        }

        #endregion

        #region INotifyPropertyChanged Members

        /// <summary>
        /// Property changed event handler
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the API Key
        /// </summary>
        public string ApiKey
        {
            get
            {
                return this.apiKey;
            }

            set
            {
                if (this.apiKey != value)
                {
                    this.apiKey = value;

                    if (!string.IsNullOrEmpty(this.apiKey))
                    {
                        this.FetchSectionNames();
                    }
                }
            }
        }

        /// <summary>
        /// Gets The New York Times Logo
        /// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Used in XAML")]
        public BitmapImage Logo
        {
            get
            {
                var streamResource = Application.GetResourceStream(
    new Uri("NYTimesSilverlightKit;component/Images/Logo.png", UriKind.Relative));

                var image = new BitmapImage();

#if SILVERLIGHT
                image.SetSource(streamResource.Stream);
#else
                image.StreamSource = streamResource.Stream;
#endif

                return image;
            }
        }

        /// <summary>
        /// Gets the section names
        /// </summary>
        public ObservableCollection<NewsSection> SectionNames { get; private set; }

        /// <summary>
        /// Gets the service status
        /// </summary>
        public string Status
        {
            get
            {
                return this.status;
            }

            private set
            {
                if (this.status != value)
                {
                    this.status = value;

                    this.TriggerPropertyChanged("Status");
                }
            }
        }

        /// <summary>
        /// Gets the copyright message
        /// </summary>
        public string Copyright
        {
            get
            {
                return this.copyright;
            }

            private set
            {
                if (this.copyright != value)
                {
                    this.copyright = value;

                    this.TriggerPropertyChanged("Copyright");
                }
            }
        }

        #endregion

        /// <summary>
        /// Trigger the property changed event
        /// </summary>
        /// <param name="propertyName">the property name</param>
        private void TriggerPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        /// <summary>
        /// Fetch the news section names
        /// </summary>
        private void FetchSectionNames()
        {
            if (this.ApiKey == null)
            {
                return;
            }

            if (SampleData.IsInDesignTool)
            {
                return;
            }

            this.SectionNames.Clear();

            var uriString = string.Format(
                CultureInfo.InvariantCulture,
                "http://api.nytimes.com/svc/news/v3/content/section-list.xml?api-key={0}",
                this.ApiKey);

            var client = new WebClient();

            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(this.OnSectionNamesDownloaded);

            client.DownloadStringAsync(new Uri(uriString, UriKind.Absolute));

            this.Status = "Loading";
        }

        /// <summary>
        /// Parse the XML once the section names are downloaded
        /// </summary>
        /// <param name="sender">the web client</param>
        /// <param name="e">the download string completed event argumetns</param>
        private void OnSectionNamesDownloaded(object sender, DownloadStringCompletedEventArgs e)
        {
            if (e.Error != null)
            {
                System.Diagnostics.Debug.WriteLine(e.Error.Message);

                return;
            }

            var xml = e.Result;

            this.ParseXml(xml);
        }

        /// <summary>
        /// Parse the result XML
        /// </summary>
        /// <param name="xml">the result set XML</param>
        private void ParseXml(string xml)
        {
            var doc = XDocument.Parse(xml);

            var resultSet = doc.Element("result_set");

            var sections = from news_section in resultSet.Element("results").Elements("news_section")
                           select new NewsSection
                           {
                               DisplayName = news_section.Element("display_name").Value,
                               Section = news_section.Element("section").Value
                           };

            foreach (var section in sections)
            {
                this.SectionNames.Add(section);
            }

            this.Copyright = resultSet.Element("copyright").Value;
            this.Status = resultSet.Element("status").Value;
        }
    }
}
